package net.lesscoding.session.impl;

import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import net.lesscoding.session.Group;
import net.lesscoding.session.GroupSession;
import net.lesscoding.session.SessionFactory;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author eleven
 * @date 2024/10/31 14:42
 * @apiNote
 */
@Slf4j
public class MemoryGroupSessionImpl implements GroupSession {

    private static Map<String, Group> groupMap = new ConcurrentHashMap<>();
    @Override
    public Group createGroup(String name, Set<String> members) {
        if (groupMap.containsKey(name)) {
            return null;
        }
        Group group = new Group(name, members, new ConcurrentHashMap<>());
        groupMap.put(name, group);

        return group;
    }

    @Override
    public Group joinGroup(String name, String member) {
        Group group = getGroup(name);
        group.getMembers().add(member);
        return group;
    }

    @Override
    public Group quitGroup(String name, String member) {
        Group group = getGroup(name);
        group.getMembers().remove(member);
        return group;
    }

    @Override
    public Group dissolveGroup(String name) {
        return groupMap.remove(name);
    }

    @Override
    public Group getGroup(String name) {
        return groupMap.getOrDefault(name, Group.EMPTY_GROUP);
    }

    @Override
    public Set<String> getGroupMembers(String name) {
        return groupMap.getOrDefault(name, Group.EMPTY_GROUP).getMembers();
    }

    @Override
    public List<Channel> getMembersChannel(String name) {
        return getGroupMembers(name).stream()
                .map(member -> SessionFactory.session().getChannel(member))
                .filter(Objects::nonNull)
                .collect(Collectors.toList())
       ;
    }

    @Override
    public Set<String> getGroupList() {
        return groupMap.keySet();
    }

    @Override
    public Group removeMember(String name, String member) {
        return groupMap.computeIfPresent(name, (key, value) -> {
            value.getMembers().remove(member);
            return value;
        });
    }
}
